//
//  ZYWebImageConst.h
//  ZYWebImage
//
//  Created by wangzhipan on 2025/3/5.
//

#ifndef ZYWebImageConst_h
#define ZYWebImageConst_h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CommonCrypto/CommonDigest.h>

typedef NS_ENUM(NSUInteger, ZYWebImageError) {
    ZYWebImageErrorBlackList = 1001,
    ZYWebImageErrorInvalidURL,
    ZYWebImageErrorUserCacnel,
    ZYWebImageErrorCancelled, // The image loading operation is cancelled before finished, during either async disk cache query, or waiting before actual network request. For actual network request error, check `NSURLErrorDomain` error domain and code.
};

typedef void(^ZYDownloadCompleted)(UIImage * _Nullable image, NSData * _Nullable imageData,NSError * _Nullable error) ;

static void SafeAsyncMainThread(void(^block)(void))
{
    if (!block) {
        return;
    }
    dispatch_async(dispatch_get_main_queue(), block);
}
// 文件名清理函数
static inline NSString *ZYSanitizeFileNameString(NSString * _Nullable fileName) {
    if ([fileName length] == 0) {
        return fileName;
    }
    // note: `:` is the only invalid char on Apple file system
    // but `/` or `\` is valid
    // \0 is also special case (which cause Foundation API treat the C string as EOF)
    NSCharacterSet* illegalFileNameCharacters = [NSCharacterSet characterSetWithCharactersInString:@"\0:"];
    return [[fileName componentsSeparatedByCharactersInSet:illegalFileNameCharacters] componentsJoinedByString:@""];
}

// 最大扩展名长度
#define ZY_MAX_FILE_EXTENSION_LENGTH 8

static inline NSString * _Nonnull ZYDiskCacheFileNameForKey(NSString * _Nullable key) {
    const char *str = key.UTF8String;
    if (str == NULL) {
        str = "";
    }
    unsigned char r[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), r);
    NSString *ext;
    // 1. Use URL path extname if valid
    NSURL *keyURL = [NSURL URLWithString:key];
    if (keyURL) {
        ext = keyURL.pathExtension;
    }
    // 2. Use file extname if valid
    if (!ext) {
        ext = key.pathExtension;
    }
    // 3. Check if extname valid on file system
    ext = ZYSanitizeFileNameString(ext);
    // File system has file name length limit, we need to check if ext is too long, we don't add it to the filename
    if (ext.length > ZY_MAX_FILE_EXTENSION_LENGTH) {
        ext = nil;
    }
    NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@",
                          r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10],
                          r[11], r[12], r[13], r[14], r[15], ext.length == 0 ? @"" : [NSString stringWithFormat:@".%@", ext]];
    return filename;
}

// 定义 weakify
#define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##object = object;

// 定义 strongify
#define strongify(object) autoreleasepool{} __strong __typeof__(object) object = weak##object;


#endif /* ZYWebImageConst_h */
